﻿//-----------------------------------------------------------------------------------------------------//
//																	                                   //
// interval.cpp  contains implementation															   //
//																									   //
// author	: Eng. Ahmed Yasser																		   //
// data		: 20-01-2015																			   //
//																	                                   //
//-----------------------------------------------------------------------------------------------------//
#include "..\include\interval.h"

interval_t create_interval(float start, int start_type, float end, int end_type)
{
	if (start > end)
		throw std::string("invalid interval");

	interval_t interval;
	interval.start = start;
	interval.start_type = start_type;
	interval.end = end;
	interval.end_type = end_type;
	return interval;
}

interval_t create_closed_closed_interval(float start, float end)
{
	return create_interval(start, CLOSED_INTERVAL, end, CLOSED_INTERVAL);
}

interval_t create_closed_opened_interval(float start, float end)
{
	return create_interval(start, CLOSED_INTERVAL, end, OPENED_INTERVAL);
}

interval_t create_opened_closed_interval(float start, float end)
{
	return create_interval(start, OPENED_INTERVAL, end, CLOSED_INTERVAL);
}

interval_t create_opened_opened_interval(float start, float end)
{
	return create_interval(start, OPENED_INTERVAL, end, OPENED_INTERVAL);
}

interval_t create_closed_infinite_interval(float start)
{
	return create_interval(start, CLOSED_INTERVAL, POSITIVE_INFINITE, INFINITE_INTERVAL);
}

interval_t create_opened_infinite_interval(float start)
{
	return create_interval(start, OPENED_INTERVAL, POSITIVE_INFINITE, INFINITE_INTERVAL);
}

interval_t create_negative_infinite_closed_interval(float end)
{
	return create_interval(NEGATIVE_INFINITE, INFINITE_INTERVAL, end, CLOSED_INTERVAL);
}

interval_t create_negative_infinite_opened_interval(float end)
{
	return create_interval(NEGATIVE_INFINITE, INFINITE_INTERVAL, end, OPENED_INTERVAL);
}

interval_t create_infinite_infinite_interval()
{
	return create_interval(NEGATIVE_INFINITE, INFINITE_INTERVAL, POSITIVE_INFINITE, INFINITE_INTERVAL);
}

std::vector<float> evaluate_interval(const interval_t& interval, float step)
{
	if (interval.end_type == INFINITE_INTERVAL || interval.start_type == INFINITE_INTERVAL)
		throw std::string("cannot evaluate infinite intervals");

	std::vector<float> xs;
	for (float x = interval.start; x <= interval.end; x += step)
		xs.push_back(x);

	return xs;
}

std::string print_interval(const interval_t& interval)
{
	std::stringstream s_stream;

	if (interval.start_type == CLOSED_INTERVAL)
		s_stream << "[";
	else if (interval.start_type == OPENED_INTERVAL || interval.start_type == INFINITE_INTERVAL )
		s_stream << "(";

	if (interval.start_type == INFINITE_INTERVAL)
	{
		if (interval.start == POSITIVE_INFINITE)
			s_stream << "INF,";
		else if (interval.start == NEGATIVE_INFINITE)
			s_stream << "-INF,";
	}
	else
		s_stream << interval.start << ",";

	if (interval.end_type == INFINITE_INTERVAL)
	{
		if (interval.end == POSITIVE_INFINITE)
			s_stream << "INF";
		else if (interval.end == NEGATIVE_INFINITE)
			s_stream << "-INF";
	}
	else
		s_stream << interval.end;

	if (interval.end_type == CLOSED_INTERVAL)
		s_stream << "]";
	else if (interval.end_type == OPENED_INTERVAL || interval.end_type == INFINITE_INTERVAL)
		s_stream << ")";

	return s_stream.str();
}
